package o2o.web.actions.user;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.jinyou.utils.common.AjaxResult;
import com.jinyou.utils.common.ValidateUtil;
import com.jinyou.utils.security.EncrypMD5;
import com.jinyouapp.common.tools.jms.model.JMSNotify;
import map.HttpRequest;
import o2o.cache.sys.SysConfigPayMemory;
import o2o.cache.user.UserInfoMemory;
import o2o.cache.user.UserOnlineImpl;
import o2o.cache.user.UserPwdMemory;
import o2o.config.dao.UserDaoSql;
import o2o.config.jms.config.JMSTypeContent;
import o2o.config.jms.sender.JmsSender;
import o2o.dao.PO.PojoTables;
import o2o.dao.PO.common.ResultInfo;
import o2o.dao.PO.common.UserType;
import o2o.dao.PO.device.door.DeviceCompanyContact;
import o2o.dao.PO.sys.SysConfigPay;
import o2o.dao.PO.user.UserInfo;
import o2o.dao.VO.user.UserAddressVO;
import o2o.dao.VO.user.UserInfoVO;
import o2o.system.data.PROMPTS;
import o2o.system.data.SYS_CONFIG_PATH;
import o2o.system.data.SYS_SETTINGS;
import o2o.utils.MultilingualResult;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import pay.config.WeixinConfig;
import wx.utils.WeixinUtil;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static wx.utils.WeixinUtil.decryptData;

@Controller
public class UserWXAction {

    //公众号---用户通过微信code登录
    @RequestMapping(method = RequestMethod.POST, value = "/user/login/byWxCode")
    @ResponseBody
    public String user_login_byOpenId(String sysAppKey, String appFlag, String code, String state) {
        System.out.println("微信code回调--code:" + code + ",state:" + state);

        String username = state;

//        //boss数据通
//        String appId = "wx0a3fc42a0de29fa2";
//        String appSecret = "7c72514c9aab0e8d701189b8698a5d22";

        if (ValidateUtil.isNull(username)) {
            return AjaxResult.errorResult("code为空，登录失败");
        }

        String gzhAppId = WeixinConfig.gzhAppId;
        String gzhAppSecret = WeixinConfig.gzhAppSecret;
        if (ValidateUtil.isNotNull(appFlag)) {
            SysConfigPay sysConfigPay2 = SysConfigPayMemory.getInstance().getByKey(sysAppKey, appFlag);
            if (null != sysConfigPay2) {
                gzhAppId = sysConfigPay2.getWxGzhAppId();
                gzhAppSecret = sysConfigPay2.getWxGzhAppSecret();
            }
        }
        //获取openid
        String openId = WeixinUtil.getUserOpenID(gzhAppId, gzhAppSecret, code);
        System.out.println(state + "：用户的openId为：" + openId);

        if (ValidateUtil.isNull(openId)) {
            return AjaxResult.errorResult("未获取到用户的openId");
        }

        boolean updateOpenId = true;
        UserInfo userInfo = null;
        if ("snsapi_base".equalsIgnoreCase(username)) {
            //非账号登录
            userInfo = UserInfoMemory.getInstance().getUserInfoByOpenId(openId);
        }
        if (null == userInfo) {
            userInfo = UserInfoMemory.getInstance().getUserInfoByOpenId(openId);
            if (null == userInfo) {
                //不存在该用户 注册用户
                boolean regSuccess = false;
                try {
                    regSuccess = User.addUser(openId, "123456", UserType.USER);
                    userInfo = UserInfoMemory.getInstance().getUserInfo(openId);
                } catch (Exception e) {
                    e.printStackTrace();
//                    return AjaxResult.errorResult("根据微信openId注册用户失败");
                    userInfo = UserInfoMemory.getInstance().getUserInfo(openId);
                    if (null != userInfo) {
                        regSuccess = true;
                    } else {
                        return AjaxResult.errorResult("根据微信openId注册用户失败");
                    }
                }
                if (!regSuccess) {
                    return AjaxResult.errorResult("根据微信openId注册用户失败，请重试");
                }

                if (null == userInfo) {
                    userInfo = UserInfoMemory.getInstance().getUserInfoByOpenId(openId);
                }
            } else {
                updateOpenId = false;
            }
        } else {
            if (openId.equalsIgnoreCase(userInfo.getWxOpenId())) {
                updateOpenId = false;
            }
        }

        if (null == userInfo) {
            return AjaxResult.errorResult("用户信息不存在");
        }

        if (updateOpenId) {
            String filed = "wxGzhOpenId";
            if (ValidateUtil.isNotNull(appFlag)) {
                filed = "wxGzhOpenId2";
            }
            //获取到用户的openId后存到用户信息
            StringBuffer sb = new StringBuffer();
            sb.append("update ").append(PojoTables.UserInfo).append(" set ").append(filed).append("='").append(openId).append("',updateUser='admin_wx_response' where username = '").append(userInfo.getUsername()).append("' and delFlag =0");
            try {
                UserDaoSql.getInstance().executeBySql(sb.toString());
            } catch (SQLException e) {
                e.printStackTrace();
                return AjaxResult.errorResult("保存用户的微信openId失败，请稍后再试");
            }
            UserInfoMemory.getInstance().modifyUserInfo(username);
            try {
                JMSNotify notify = JMSNotify.getInstance().setType(JMSTypeContent.USER_INFO_MODIFY).setStr01(username);//o2o.business.jms  MQDataBusiness
                JmsSender.setTopicSender(notify);
            } catch (Exception e) {
            }
            if (ValidateUtil.isNull(openId)) {
                return AjaxResult.errorResult("微信openId不能为空");
            }
        }


        //获取用户信息
        ResultInfo resultInfo = UserLogin.loginByWxOpenId(appFlag, openId, UserType.USER);
        if (!resultInfo.isSuccess()) {
            return AjaxResult.errorResult(resultInfo.getError());
        }
        UserInfoVO infoVO = (UserInfoVO) resultInfo.getObj();
        ResultInfo info = User.getUserAddress(infoVO.getUsername());
        if (info.isSuccess() && null != info.getObj()) {
            infoVO.setUserAddress((List<UserAddressVO>) info.getObj());
        }

        return AjaxResult.successResult(infoVO);
    }


    //公众号---用户通过微信code获取openId
    @RequestMapping(method = RequestMethod.POST, value = "/user/wx/gzh/openId")
    @ResponseBody
    public String user_login_by(String sysAppKey, String appFlag, String code) {
        System.out.println("微信code回调--code:" + code);
        if (ValidateUtil.isNull(code)) {
            return AjaxResult.errorResult("code为空");
        }

        String gzhAppId = WeixinConfig.gzhAppId;
        String gzhAppSecret = WeixinConfig.gzhAppSecret;
        if (ValidateUtil.isNotNull(appFlag)) {
            SysConfigPay sysConfigPay2 = SysConfigPayMemory.getInstance().getByKey(sysAppKey, appFlag);
            if (null != sysConfigPay2) {
                gzhAppId = sysConfigPay2.getWxGzhAppId();
                gzhAppSecret = sysConfigPay2.getWxGzhAppSecret();
            }
        }
        //获取openid
        String openId = WeixinUtil.getUserOpenID(gzhAppId, gzhAppSecret, code);
        System.out.println("用户的openId为：" + openId);

        if (ValidateUtil.isNull(openId)) {
            return AjaxResult.errorResult("未获取到用户的openId");
        }
        UserInfo userInfo = UserInfoMemory.getInstance().getUserInfoByGzhOpenId(openId);
        if (null == userInfo) {
            System.out.println("未找到用户");
            userInfo = new UserInfo();
            userInfo.setWxGzhOpenId(openId);
        }
        return AjaxResult.successResult(userInfo);
    }


    //用户通过微信openId登录
    @RequestMapping(method = RequestMethod.POST, value = "/user/login/byWxOpenId")
    @ResponseBody
    public String user_login_byOpenId(String appFlag, String wxOpenId, String wxXcxOpenId, Integer needBindAccount) {  // 不传或者传0，代表不需要绑定账号
        if (ValidateUtil.isNull(wxOpenId) && ValidateUtil.isNull(wxXcxOpenId)) {
            return AjaxResult.errorResult("微信openId不能为空");
        }
        ResultInfo resultInfo = null;
        if (null != wxXcxOpenId) {
            resultInfo = UserLogin.loginByWxXcxOpenId(appFlag, wxXcxOpenId, UserType.USER, needBindAccount);
        } else if (null != wxOpenId) {
            resultInfo = UserLogin.loginByWxOpenId(appFlag, wxOpenId, UserType.USER, needBindAccount);
        } else {
            return AjaxResult.errorResult("请选择登录方式");
        }

        //获取用户信息
//        ResultInfo resultInfo = UserLogin.loginByWxOpenId(wxOpenId, UserType.USER, needBindAccount);
        if (null == resultInfo) {
            return AjaxResult.errorResult("登录失败，请稍后再试");
        }
        if (!resultInfo.isSuccess()) {
            return AjaxResult.errorResult(resultInfo.getError());
        }
        UserInfoVO infoVO = (UserInfoVO) resultInfo.getObj();
        ResultInfo info = User.getUserAddress(infoVO.getUsername());
        if (info.isSuccess() && null != info.getObj()) {
            infoVO.setUserAddress((List<UserAddressVO>) info.getObj());
        }

        return AjaxResult.successResult(infoVO);
    }


    //修改openId
    @RequestMapping(method = RequestMethod.POST, value = "/user/info/wxOpenId/modify")
    @ResponseBody
    public String modifyUserInfo(String sysAppKey, String appFlag, String token, String wxOpenId, String wxXcxOpenId, String signPhoto) {
        //验证用户有效性
        UserInfo user = UserInfoMemory.getInstance().getUserInfo(UserOnlineImpl.getInstance().get(token));
        if (user == null) {
            return AjaxResult.errorLogoutResult();
        }

        if (ValidateUtil.isNull(wxOpenId)) {
            wxOpenId = user.getWxOpenId();
        }

        if (ValidateUtil.isNull(wxXcxOpenId)) {
            wxXcxOpenId = user.getWxXcxOpenId();
        }

        //如果传入了头像 则修改头像
        String signPh = "";
        if (ValidateUtil.isNotNull(signPhoto)) {
            signPh = ",signPhoto='" + signPhoto + "'";
        }

        String filed = "wxOpenId";
        String filed2 = "wxXcxOpenId";
        if (ValidateUtil.isNotNull(appFlag)) {
            filed = "wxOpenId2";
            filed2 = "wxXcxOpenId2";
        }
        StringBuilder sb = new StringBuilder();
        sb.append("update ").append(PojoTables.UserInfo).append(" set ").append(filed).append("='").append(wxOpenId)
                .append("',").append(filed2).append("='").append(wxXcxOpenId).append("',updateUser = '").append(user.getUsername())
                .append("'").append(signPh).append(" where delFlag = 0 and username = '").append(user.getUsername()).append("'");

        try {
            UserDaoSql.getInstance().executeBySql(sb.toString());
        } catch (SQLException e) {
            e.printStackTrace();
            return AjaxResult.errorResult("修改个人信息失败，请稍后再试");
        }

//        UserInfoMemory.getInstance().modifyUserInfo(USER.getUsername());
        //同步修改用户信息
        JMSNotify notify = JMSNotify.getInstance().setType(JMSTypeContent.USER_INFO_MODIFY).setStr01(user.getUsername());//o2o.business.jms  MQDataBusiness
        JmsSender.setTopicSender(notify);

        return AjaxResult.successResult();
    }


    //小程序根据code保存用户的openId
    @RequestMapping(method = RequestMethod.POST, value = "/user/wx/little/openId/get")
    @ResponseBody
    public String getCodeOpenId(String sysAppKey, String appFlag, String code, String state,
                                Integer needSessionKey // 获取session_key和openId
    ) {
        Map<String, String> map = new HashMap<>();
        map.put("code", code);
        map.put("state", state);
        //处理下一步
        System.out.println("微信code回调--code:" + code + ",state:" + state);

        //小程序
        String appId = WeixinConfig.xcxAppId;
        String appSecret = WeixinConfig.xcxAppSecret;

        String filed = "wxXcxOpenId";
        if (ValidateUtil.isNotNull(appFlag)) {
            SysConfigPay sysConfigPay2 = SysConfigPayMemory.getInstance().getByKey(sysAppKey, appFlag);
            if (null != sysConfigPay2) {
                filed = "wxXcxOpenId2";
                appId = sysConfigPay2.getWxXcxAppId();
                appSecret = sysConfigPay2.getWxXcxAppSecret();
            }
        }

        String username = state;
        if (ValidateUtil.isNull(username)) {
            return AjaxResult.errorResult("用户账号不能为空");
        }
        Boolean needSession = false;
        if (null != needSessionKey) {
            needSession = true;
        }

        String openId = WeixinUtil.getUserOpenIDLittle(appId, appSecret, code, needSession);
        if (ValidateUtil.isNotNull(openId)) {
            StringBuilder sb = new StringBuilder();
            sb.append("update ").append(PojoTables.UserInfo).append(" set  ").append(filed).append("='").append(openId).append("',updateUser = '").append(username).append("' where delFlag = 0 and username = '").append(username).append("'");

            try {
                UserDaoSql.getInstance().executeBySql(sb.toString());
            } catch (SQLException e) {
                e.printStackTrace();
                return AjaxResult.errorResult("修改个人信息失败，请稍后再试");
            }

//        UserInfoMemory.getInstance().modifyUserInfo(USER.getUsername());
            //同步修改用户信息
            JMSNotify notify = JMSNotify.getInstance().setType(JMSTypeContent.USER_INFO_MODIFY).setStr01(username);//o2o.business.jms  MQDataBusiness
            JmsSender.setTopicSender(notify);
        }

        return AjaxResult.successResult(openId);
    }

    //根据微信openId绑定本地账号5.28
    @RequestMapping(method = RequestMethod.POST, value = "/user/wxOpenId/bind")
    @ResponseBody
    public String user_login_byOpenId_bind(String sysAppKey, String appFlag,
                                           String username, String telCode, String password,
                                           String wxOpenId, String wxGzhOpenId, String wxXcxOpenId,
                                           String signPhoto, String lang,
                                           Integer isXcx // 是否为小程序， 是的话可以不用验证码验证
    ) {  // 不传或者传0，代表不需要绑定账号
        if (ValidateUtil.isNull(wxOpenId) && ValidateUtil.isNull(wxXcxOpenId) && ValidateUtil.isNull(wxGzhOpenId)) {
            return AjaxResult.errorResult("微信openId不能为空");
        }
        if (ValidateUtil.isNull(username)) {
            return AjaxResult.errorResult("手机号不能为空");
        }

        Boolean isXcx_ = false;
        if (ValidateUtil.isAbsInteger(isXcx)) {
            isXcx_ = true;
        }
        if (ValidateUtil.isNull(telCode) && 0 != 1 - isXcx) {
            return AjaxResult.errorResult("验证码不能为空");
        }

        ResultInfo resultInfo = UserLogin.loginByTelCodeAndWxOpenId(username, telCode, UserType.USER, password, isXcx_);

        if (null == resultInfo) {
            return AjaxResult.errorResult("登录失败，请稍后再试");
        }
        if (!resultInfo.isSuccess()) {
            return MultilingualResult.errorResultV2(resultInfo.getError(), lang);
//            return AjaxResult.errorResult(resultInfo.getError());
        }
        UserInfoVO infoVO = (UserInfoVO) resultInfo.getObj();

        String sql = "";
        if (null != wxOpenId) {
            if (ValidateUtil.isNotNull(appFlag)) {
                sql = "wxOpenId2 = '" + wxOpenId + "',";
            } else {
                sql = "wxOpenId = '" + wxOpenId + "',";
            }
        }
        if (null != wxXcxOpenId) {
            if (ValidateUtil.isNotNull(appFlag)) {
                sql = "wxXcxOpenId2 = '" + wxXcxOpenId + "',";
            } else {
                sql = "wxXcxOpenId = '" + wxXcxOpenId + "',";
            }
        }
        if (null != wxGzhOpenId) {
            if (ValidateUtil.isNotNull(appFlag)) {
                sql = "wxGzhOpenId2 = '" + wxGzhOpenId + "',";
            } else {
                sql = "wxGzhOpenId = '" + wxGzhOpenId + "',";
            }
        }

//        if (user == null) {
//            if (null != SYS_SETTINGS.SHOP_DEFAULT_PSW && 0 == 1 - SYS_SETTINGS.SHOP_DEFAULT_PSW) {
//                psw = info.getUsername().substring(5, 11);
//            }
//            // 注册一个用户
//            ResultInfo resultInfo = UserLogin.registerByTelCode(info.getUsername(), true, psw, telCode); //单独注册接口
//            if (null == resultInfo) {
//                return AjaxResult.errorResult("注册失败，请稍后再试");
//            }
//            if (null != resultInfo && !resultInfo.isSuccess()) {
//                return AjaxResult.errorResult(resultInfo.getError());
//            }
//        } else {
//
//        }

        //如果传入了头像 则修改头像
        String signPh = "";
        if (ValidateUtil.isNotNull(signPhoto)) {
            signPh = ",signPhoto='" + signPhoto + "'";
            infoVO.setSignPhoto(signPhoto);
        }


        // 用wxOpenId绑定账号
        StringBuilder sb = new StringBuilder();
        sb.append("update ").append(PojoTables.UserInfo)
                .append(" set ").append(sql)
                .append("updateUser = '").append(username).append("'")
                .append(signPh)
                .append(" where delFlag = 0 and username = '").append(username).append("'");

        try {
            UserDaoSql.getInstance().executeBySql(sb.toString());
        } catch (SQLException e) {
            e.printStackTrace();
            return AjaxResult.errorResult("修改个人信息失败，请稍后再试");
        }

        UserInfoMemory.getInstance().modifyUserInfo(username);

        //同步修改用户信息
        JMSNotify notify = JMSNotify.getInstance().setType(JMSTypeContent.USER_INFO_MODIFY).setStr01(username);//o2o.business.jms  MQDataBusiness
        JmsSender.setTopicSender(notify);


        if (ValidateUtil.isNotNull(wxOpenId)) {
            if (null != SYS_SETTINGS.IS_OPEN_DISTRIBUTION && 0 == 1 - SYS_SETTINGS.IS_OPEN_DISTRIBUTION) {
                //开启分销模式  修改用户的账号
                String requrstStr = HttpRequest.sendPost(SYS_CONFIG_PATH.FEN_XIAO_SERVICE_URL + "api/distribute/user/relation/username/update"
                        , "username=" + username + "&openId=" + wxOpenId + "&sysCustomer=" + SYS_CONFIG_PATH.FEN_XIAO_SERVICE_KEY);
                DeviceCompanyContact companyContact = new Gson().fromJson(requrstStr, DeviceCompanyContact.class);
                if (null == companyContact) {
                    System.out.println("分销处理失败[更新用户的openId对应的的账号失败]");
                }
                if (0 == 1 - companyContact.getStatus()) {
                    System.out.println("分销处理-更新用户的openId对应的的账号失败");
                }
            }
        }


        //如果传入了密码，则修改对应的密码 add by zhuwx 2018-10-23
        if (ValidateUtil.isNotNull(password)) {
            // 密码加密处理
            try {
                password = EncrypMD5.eccrypt(password);
            } catch (Exception e) {
                e.printStackTrace();
                return MultilingualResult.errorResultV2(PROMPTS.PASSWORD_ENCRYPTION_FAILED, lang);
            }
            //修改密码
            if (!modifyUserPassword(username, password)) {
                MultilingualResult.errorResultV2(PROMPTS.MODIFICATION_PASSWORD_FAILED, lang);
            }
            UserPwdMemory.getInstance().modifyPassword(username, password);
            //同步修改密码
            JMSNotify notify2 = JMSNotify.getInstance().setType(JMSTypeContent.USER_PASSWORD_MODIFY).setStr01(username).setStr02(password);//o2o.business.jms  MQDataBusiness
            JmsSender.setTopicSender(notify2);
        }


        return AjaxResult.successResult(infoVO);
    }


    //小程序根据code换回openId
    @RequestMapping(method = RequestMethod.POST, value = "/user/wx/xcx/openId/get")
    @ResponseBody
    public String getCodeXcxOpenId(String code, Long agentId,
                                   String sysAppKey, String appFlag,
                                   Integer needSessionKey // 获取session_key和openId
    ) {

        if (ValidateUtil.isNull(code)) {
            return AjaxResult.errorResult("code不能为空");
        }

        Boolean needSession = false;
        if (null != needSessionKey) {
            needSession = true;
        }

        //小程序
        String appId = WeixinConfig.xcxAppId;
        String appSecret = WeixinConfig.xcxAppSecret;

        if (ValidateUtil.isID(agentId)) {
            SysConfigPay sysConfigPay = SysConfigPayMemory.getInstance().getByAgentId(agentId, appFlag);
            if (null != sysConfigPay) {
                appId = sysConfigPay.getWxXcxAppId();
                appSecret = sysConfigPay.getWxXcxAppSecret();
            } else if (ValidateUtil.isNotNull(appFlag)) {
                SysConfigPay sysConfigPay2 = SysConfigPayMemory.getInstance().getByKey(sysAppKey, appFlag);
                if (null != sysConfigPay2) {
                    appId = sysConfigPay2.getWxXcxAppId();
                    appSecret = sysConfigPay2.getWxXcxAppSecret();
                }
            }
        } else if (ValidateUtil.isNotNull(appFlag)) {
            SysConfigPay sysConfigPay2 = SysConfigPayMemory.getInstance().getByKey(sysAppKey, appFlag);
            if (null != sysConfigPay2) {
                appId = sysConfigPay2.getWxXcxAppId();
                appSecret = sysConfigPay2.getWxXcxAppSecret();
            }
        }


        String openId = WeixinUtil.getUserOpenIDLittle(appId, appSecret, code, needSession);
        // 返回seesion_key和openId
        if (needSession) {
            return AjaxResult.successResult(JSONObject.parseObject(openId));
        }
        return AjaxResult.successResult(openId);
    }


    /**
     * 获取微信手机号
     *
     * @param encryptedData 包括敏感数据在内的完整用户信息的加密数据
     * @param sessionKey    会话密钥
     * @param iv            加密算法的初始向量
     * @return
     */
    @RequestMapping(method = RequestMethod.POST, value = "/user/wx/xcx/phone/get")
    @ResponseBody
    public String getPhoneNumber(String encryptedData, String sessionKey, String iv) {

        if (ValidateUtil.isNull(encryptedData) || ValidateUtil.isNull(sessionKey) || ValidateUtil.isNull(iv)) {
            return AjaxResult.errorResult("信息不全，请补全信息");
        }

        JSONObject jsonObject = decryptData(encryptedData, sessionKey, iv);

        return AjaxResult.successResult(jsonObject);
    }

    //----------------------------------通用方法
    //修改密码
    private boolean modifyUserPassword(String username, String password) {
        String sql = "update " + PojoTables.UserPasswordInfo + " set password = '" + password + "' where username = '" + username + "' and delFlag = 0";
        try {
            UserDaoSql.getInstance().executeBySql(sql);
        } catch (SQLException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
}

